///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jun 17 2015)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////

#include "Frame_Main.h"
#include "Dialog_Settings.h"
#include "FontPixelMatrix.h"

///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(Frame_Main, wxFrame)
	//EVT_UPDATE_UI(wxID_MAIN, Frame_Main::wxEvent_OnUpdateUI)
    EVT_PAINT(Frame_Main::wxEvent_OnPaint)
    EVT_COMBOBOX(wxID_COMBO_FONT_FACE, Frame_Main::wxEvent_OnFontSizeSelected)
	EVT_TEXT(wxID_CTRL_SPIN_FONT_SIZE, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TOOL(wxID_TOOL_FONT_BOLD, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TOOL(wxID_TOOL_FONT_ITALIC, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TOOL(wxID_TOOL_FONT_TOP_CUT, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TEXT(wxID_CTRL_SPIN_TOP_CUT, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TOOL(wxID_TOOL_FONT_BOTTOM_CUT, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TEXT(wxID_CTRL_SPIN_BOTTOM_CUT, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TOOL(wxID_TOOL_FONT_FIXED_WIDTH, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TEXT(wxID_CTRL_SPIN_FIXED_WIDTH, Frame_Main::wxEvent_OnRefreshPaint)
    EVT_TOOL(wxID_TOOL_FONT_SETTINGS, Frame_Main::wxEvent_OnSettings)
    EVT_TEXT(wxID_CTRL_TEXT_INPUT, Frame_Main::wxEvent_OnTextEvent)
END_EVENT_TABLE()
Frame_Main::Frame_Main( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
	this->SetSizeHints( wxSize( 800,480 ), wxDefaultSize );

	// Create tools bar.
	_createToolbar();

	// Create main window frame.
	wxBoxSizer* pclsSizer_RootSizer = new wxBoxSizer( wxVERTICAL );
	if(NULL != pclsSizer_RootSizer)
    {
        // Root panel and sizer.
        m_pclsPanel_RootPanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
        wxBoxSizer* pclsSizer_RootPanelSizer = new wxBoxSizer( wxVERTICAL );

        // Text input box.
        wxBoxSizer* pclsSizer_Input = new wxBoxSizer( wxHORIZONTAL );
        m_pclsTextCtrl_Input = new wxTextCtrl( m_pclsPanel_RootPanel, wxID_CTRL_TEXT_INPUT, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
        pclsSizer_Input->Add( m_pclsTextCtrl_Input, 1, wxALIGN_CENTER_VERTICAL, 5 );

        // Pixelated text output box.
        wxBoxSizer* pclsSizer_Output = new wxBoxSizer( wxVERTICAL );
        // Splitter window frame.
        m_pclsSplitter_OutPut = new wxSplitterWindow( m_pclsPanel_RootPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D );
        m_pclsSplitter_OutPut->SetMinimumPaneSize( 164 );
        m_pclsSplitter_OutPut->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWFRAME ) );

        // Pixelated text graph paint panel.
        m_pclsScrolledWindow_Paint = new wxScrolledWindow( m_pclsSplitter_OutPut, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxVSCROLL );
        m_pclsScrolledWindow_Paint->SetScrollRate( 5, 5 );
        wxBoxSizer* pclsSizer_PixelatedText = new wxBoxSizer( wxVERTICAL );
        m_pclsPanel_PaintPanel = new Panel_PixelatedTextPanel(m_pclsScrolledWindow_Paint, wxID_ANY, wxDefaultPosition);
        pclsSizer_PixelatedText->Add( m_pclsPanel_PaintPanel, 1, wxEXPAND, 5);
        m_pclsScrolledWindow_Paint->SetSizer( pclsSizer_PixelatedText );
        pclsSizer_PixelatedText->Layout();
        m_pclsScrolledWindow_Paint->Layout();
        //pclsSizer_PixelatedText->Fit( m_pclsScrolledWindow_Paint );

        // Pixelated text model data output panel.
        m_pclsPanel_OutputText = new wxPanel( m_pclsSplitter_OutPut, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
        wxBoxSizer* pclsSizer_OutputTextRoot = new wxBoxSizer( wxVERTICAL );
        m_pclsTextCtrl_Output = new wxTextCtrl( m_pclsPanel_OutputText, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
        pclsSizer_OutputTextRoot->Add( m_pclsTextCtrl_Output, 1, wxALL|wxEXPAND, 2 );
        m_pclsPanel_OutputText->SetSizer( pclsSizer_OutputTextRoot );
        m_pclsPanel_OutputText->Layout();
        //pclsSizer_OutputTextRoot->Fit( m_pclsPanel_OutputText );

        // Add sub panel to splitter window set.
        m_pclsSplitter_OutPut->SplitHorizontally( m_pclsScrolledWindow_Paint, m_pclsPanel_OutputText, 82 );

        // Add splitter controller to text-output box.
        pclsSizer_Output->Add( m_pclsSplitter_OutPut, 1, wxEXPAND, 5 );

        // Add output sizer box to root sizer.
        pclsSizer_RootPanelSizer->Add( pclsSizer_Input, 0, wxALL|wxEXPAND, 5 );
        pclsSizer_RootPanelSizer->Add( pclsSizer_Output, 1, wxEXPAND, 5 );

        // Add root panel to root sizer.
        m_pclsPanel_RootPanel->SetSizer( pclsSizer_RootPanelSizer );
        m_pclsPanel_RootPanel->Layout();
        pclsSizer_RootPanelSizer->Fit( m_pclsPanel_RootPanel );
        pclsSizer_RootSizer->Add( m_pclsPanel_RootPanel, 1, wxEXPAND, 5 );
        SetSizer( pclsSizer_RootSizer );

        m_pclsStatusBar_Main = CreateStatusBar( 1, wxST_SIZEGRIP, wxID_ANY );
    }

    Layout();

    // Set frame object startup position to screen center.
    Centre( wxBOTH );

	_initialize();
}

void Frame_Main::_createToolbar(void)
{
    /*----------------------------------*/
	/* Initialize						*/
	/*----------------------------------*/
	m_pclsToolBar_FontSet = CreateToolBar(wxTB_HORIZONTAL, wxID_ANY);

	/*----------------------------------*/
	/* Process							*/
	/*----------------------------------*/
    if(NULL != m_pclsToolBar_FontSet)
    {
        // Create combo box for choose font.
        m_pclsComboBox_FontList = new wxComboBox(           m_pclsToolBar_FontSet,
                                                            wxID_COMBO_FONT_FACE,
                                                            wxEmptyString,
                                                            wxDefaultPosition,
                                                            wxSize( 150,-1 ),
                                                            0,
                                                            NULL,
                                                            wxCB_READONLY|wxCB_SORT);
        m_pclsToolBar_FontSet->AddControl( m_pclsComboBox_FontList );
        // Set font size.
        m_pclsSpinCtrl_FontSize = new wxSpinCtrl(           m_pclsToolBar_FontSet,
                                                            wxID_CTRL_SPIN_FONT_SIZE,
                                                            wxEmptyString,
                                                            wxDefaultPosition,
                                                            wxSize( 65,-1 ),
                                                            wxSP_ARROW_KEYS,
                                                            6,
                                                            256,
                                                            6);
        m_pclsToolBar_FontSet->AddControl( m_pclsSpinCtrl_FontSize );

        m_pclsToolBar_FontSet->AddSeparator();

        // Add bold font switch button.
        m_pclsTool_Bold = m_pclsToolBar_FontSet->AddTool(   wxID_TOOL_FONT_BOLD,
                                                            wxT("Bold"),
                                                            wxBitmap( wxT("RES_ID_TOOL_ICON_IMAGE_FONT_BOLD"), wxBITMAP_TYPE_PNG_RESOURCE),
                                                            wxNullBitmap, wxITEM_CHECK,
                                                            wxT("Font bold"),
                                                            wxT("Font Bold."),
                                                            NULL);
        // Add Italic font switch button.
        m_pclsTool_Italic = m_pclsToolBar_FontSet->AddTool( wxID_TOOL_FONT_ITALIC,
                                                            wxT("Italic"),
                                                            wxBitmap(wxT("RES_ID_TOOL_ICON_IMAGE_FONT_ITALIC"), wxBITMAP_TYPE_PNG_RESOURCE),
                                                            wxNullBitmap, wxITEM_CHECK,
                                                            wxT("Italic font"),
                                                            wxT("Italic font."),
                                                            NULL);

        m_pclsToolBar_FontSet->AddSeparator();

        // Add Top-cut switch button and value set.
        m_pclsTool_TopCut = m_pclsToolBar_FontSet->AddTool( wxID_TOOL_FONT_TOP_CUT,
                                                            wxT("Top Cut"),
                                                            wxBitmap(wxT("RES_ID_TOOL_ICON_IMAGE_FONT_TOP_CUT"), wxBITMAP_TYPE_PNG_RESOURCE),
                                                            wxNullBitmap,
                                                            wxITEM_CHECK,
                                                            wxT("Top Cut"),
                                                            wxT("Cut some pixels at the font top."),
                                                            NULL);
        m_pclsSpinCtrl_TopCutValue = new wxSpinCtrl(        m_pclsToolBar_FontSet,
                                                            wxID_CTRL_SPIN_TOP_CUT,
                                                            wxEmptyString,
                                                            wxDefaultPosition,
                                                            wxSize( 50,-1 ),
                                                            wxSP_ARROW_KEYS,
                                                            0,
                                                            128,
                                                            0);
        m_pclsToolBar_FontSet->AddControl( m_pclsSpinCtrl_TopCutValue );

        // Add Bottom-cut switch button and value set.
        m_pclsTool_BottomCut = m_pclsToolBar_FontSet->AddTool( wxID_TOOL_FONT_BOTTOM_CUT,
                                                            wxT("BottomCut"),
                                                            wxBitmap(wxT("RES_ID_TOOL_ICON_IMAGE_FONT_BOTTOM_CUT"), wxBITMAP_TYPE_PNG_RESOURCE),
                                                            wxNullBitmap,
                                                            wxITEM_CHECK,
                                                            wxT("Bottom Cut"),
                                                            wxT("Cut some pixels at the font bottom."),
                                                            NULL);
        m_pclsSpinCtrl_BottomCutValue = new wxSpinCtrl(     m_pclsToolBar_FontSet,
                                                            wxID_CTRL_SPIN_BOTTOM_CUT,
                                                            wxEmptyString,
                                                            wxDefaultPosition,
                                                            wxSize( 50,-1 ),
                                                            wxSP_ARROW_KEYS,
                                                            0,
                                                            128,
                                                            0);
        m_pclsToolBar_FontSet->AddControl( m_pclsSpinCtrl_BottomCutValue );

        // Add Force-width switch button and value set.
        m_pclsTool_ForceFixedWidth = m_pclsToolBar_FontSet->AddTool( wxID_TOOL_FONT_FIXED_WIDTH,
                                                            wxT("ForceWidth"),
                                                            wxBitmap(wxT("RES_ID_TOOL_ICON_IMAGE_FONT_FIXED_WIDTH"), wxBITMAP_TYPE_PNG_RESOURCE),
                                                            wxNullBitmap,
                                                            wxITEM_CHECK,
                                                            wxT("Force Fixed Font Width"),
                                                            wxT("Use a fixed half-width character width value, force process as monospaced."),
                                                            NULL);
        m_pclsSpinCtrl_FixedWidthValue = new wxSpinCtrl(    m_pclsToolBar_FontSet,
                                                            wxID_CTRL_SPIN_FIXED_WIDTH,
                                                            wxEmptyString,
                                                            wxDefaultPosition,
                                                            wxSize( 50,-1 ),
                                                            wxSP_ARROW_KEYS,
                                                            1,
                                                            256,
                                                            0);
        m_pclsToolBar_FontSet->AddControl( m_pclsSpinCtrl_FixedWidthValue );

        m_pclsToolBar_FontSet->AddSeparator();

        // Add setting button.
        m_pclsTool_Settings = m_pclsToolBar_FontSet->AddTool( wxID_TOOL_FONT_SETTINGS,
                                                            wxT("Settings"),
                                                            wxBitmap(wxT("RES_ID_TOOL_ICON_IMAGE_SETTINGS"), wxBITMAP_TYPE_PNG_RESOURCE),
                                                            wxNullBitmap,
                                                            wxITEM_NORMAL,
                                                            wxT("Settings"),
                                                            wxT("Settings."),
                                                            NULL);
        // Resize tool bar at finalize.
        m_pclsToolBar_FontSet->Realize();
    }
}

void Frame_Main::_resizePaintPanel(void)
{
	wxSize				clsParentWindowSize;

	clsParentWindowSize = m_pclsScrolledWindow_Paint->GetSize();
	m_pclsPanel_PaintPanel->SetPixelNumber(clsParentWindowSize.GetWidth()/4+164, m_pclsSpinCtrl_FontSize->GetValue());
	m_pclsPanel_PaintPanel->CleanPanel();
	m_pclsScrolledWindow_Paint->Layout();
}

void Frame_Main::_initialize(void)
{
	// Enumerate usable font.
	_enumFonts();
	// Set font panel color.
	m_pclsPanel_PaintPanel->SetPixelColor(wxColor(0, 0, 0, 255));
	m_pclsPanel_PaintPanel->SetBackgroundColor(wxColor(255, 255, 255));
	m_pclsScrolledWindow_Paint->SetBackgroundColour( wxColour(255, 255, 255) );
	m_pclsPanel_PaintPanel->SetFocusBorderColor(wxColor(0, 0, 255, 255));
    m_pclsPanel_PaintPanel->SetGridVisibled(true);
	m_pclsPanel_PaintPanel->SetEdgeWidth(0);
	m_pclsPanel_PaintPanel->SetPixelSize(4);
	_resizePaintPanel();
}

void Frame_Main::_paintFont(void)
{
	FontPixelMatrix		clsPixelMatrixFontObject;
	int32_t				iFontSize, iTopCutValue, iBottomCutValue, iFixedWidth;
	uint32_t			uiCharacterIndex = 0;
	int32_t				iFontGraphWidth;
	wxUniChar			cTextCharacter;
	wxString			strSourceText;
	wxFontStyle			eIsItalc;
	wxFontWeight		eIsBold;

	// Resize paint panel.
	_resizePaintPanel();
	// Get font size in pixel;
	iFontSize = m_pclsSpinCtrl_FontSize->GetValue();
	eIsItalc = m_pclsTool_Italic->IsToggled()?wxFONTSTYLE_ITALIC:wxFONTSTYLE_NORMAL;
	eIsBold = m_pclsTool_Bold->IsToggled()?wxFONTWEIGHT_BOLD:wxFONTWEIGHT_NORMAL;

	if(6 > iFontSize)
	{
		iFontSize = 6;
	}
	if(true == m_pclsTool_TopCut->IsToggled())
	{
		iTopCutValue = m_pclsSpinCtrl_TopCutValue->GetValue();
	}
	else
	{
		iTopCutValue = 0;
	}
	if(true == m_pclsTool_BottomCut->IsToggled())
	{
        iBottomCutValue = m_pclsSpinCtrl_BottomCutValue->GetValue();
	}
	else
	{
		iBottomCutValue = 0;
	}
	if(true == m_pclsTool_ForceFixedWidth->IsToggled())
	{
        iFixedWidth = m_pclsSpinCtrl_FixedWidthValue->GetValue();
	}
	else
	{
		iFixedWidth = -1;
	}
	clsPixelMatrixFontObject.Create(iFontSize, wxFONTFAMILY_DECORATIVE, eIsItalc, eIsBold, false, m_pclsComboBox_FontList->GetValue());

	m_pclsPanel_PaintPanel->CleanPanel();
	strSourceText = m_pclsTextCtrl_Input->GetValue();
	while(uiCharacterIndex < strSourceText.Length())
	{
		cTextCharacter = strSourceText.GetChar(uiCharacterIndex++);
        if(0 < iFixedWidth)
        {
            if(false == cTextCharacter.IsAscii())
            {
                iFontGraphWidth = iFixedWidth * 2;
            }
            else
            {
                iFontGraphWidth = iFixedWidth;
            }
        }
        else
        {
            iFontGraphWidth = -1;
        }
        clsPixelMatrixFontObject.SetCharacter(cTextCharacter, iFontGraphWidth, iTopCutValue, iBottomCutValue);
        m_pclsPanel_PaintPanel->AppendCharacter(clsPixelMatrixFontObject.ToBitmap());
	}
	m_pclsPanel_PaintPanel->RefreshDisplay();
}

void Frame_Main::OnTextEvent(wxCommandEvent &event)
{
	m_pclsTextCtrl_Output->Clear();
	_paintFont();
}

void Frame_Main::OnRefreshPaint(void)
{
	_paintFont();
}

void Frame_Main::OnPaint(wxPaintEvent &event)
{
	_paintFont();
}

void Frame_Main::OnFontSizeSelected(wxCommandEvent &event)
{
	_paintFont();
}

void Frame_Main::OnFontFaceSelected(wxCommandEvent &event)
{
	_paintFont();
}

void Frame_Main::AppendFontFace(wxString& strFontFace)
{
    m_pclsComboBox_FontList->Append(strFontFace);
}

bool Frame_Main::Show(bool bShow)
{
	bool	bResult;

	bResult = wxFrame::Show(bShow);
	if((NULL != m_pclsComboBox_FontList) && ((true == bResult)))
	{
        if(0 < m_pclsComboBox_FontList->GetCount())
		{
			m_pclsComboBox_FontList->SetSelection(0);
		}
	}
	return bResult;
}

void Frame_Main::_enumFonts(void)
{
	wxFontEnumerator	clsEnumFonts;
	wxArrayString		strFontNames;

	strFontNames = clsEnumFonts.GetFacenames(wxFONTENCODING_DEFAULT,false);
	for(uint32_t i=0;i<strFontNames.size();i++)
	{
		if(0 != strFontNames[i].Find("@"))
		{
			m_pclsComboBox_FontList->Append(strFontNames[i]);
		}
	}

	uint32_t uiCount = m_pclsComboBox_FontList->GetCount();
	if(0 < uiCount)
	{
		m_pclsComboBox_FontList->SetSelection(0);
	}
	else
	{
        m_pclsTextCtrl_Input->Enable(false);
	}
}

void Frame_Main::OnSettings(wxCommandEvent &event)
{
	Dialog_Settings*		pclsDialog_Settings;

	pclsDialog_Settings = new Dialog_Settings(this);
	if(NULL != pclsDialog_Settings)
	{
		pclsDialog_Settings->ShowModal();

		delete pclsDialog_Settings;
	}
}

Frame_Main::~Frame_Main()
{

}
